package com.kc.business.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.kc.business.domain.dto.BizOrderCompareStatisticsDTO;
import com.kc.business.domain.order.entity.BizCancelOrderStatistics;
import com.kc.business.domain.order.entity.BizOrderStatistics;
import com.kc.business.domain.query.BizOrderStatisticsQuery;
import com.kc.business.mapper.BizCancelOrderStatisticsMapper;
import com.kc.business.service.BizCancelOrderStatisticsService;
import com.kc.business.service.BizOrderStatisticsService;
import com.kc.common.utils.StringUtils;
import com.kc.common.utils.base.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName BizCancelOrderStatisticsServiceServiceImpl
 * @Description TODO
 * @Author wangdongliang
 * @Date 2021/5/20 14:16
 */
@Service
@Slf4j
public class BizCancelOrderStatisticsServiceImpl implements BizCancelOrderStatisticsService {
    @Resource
    private BizCancelOrderStatisticsMapper bizCancelOrderStatisticsMapper;
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private BizOrderStatisticsService bizOrderStatisticsService;
    @Override
    public List<BizCancelOrderStatistics> getList(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        List<BizCancelOrderStatistics> bizOrderStatisticsList = new ArrayList<>();
        //日期处理
        String endDate = bizOrderStatisticsQuery.getEndDate();
        String beginDate = bizOrderStatisticsQuery.getBeginDate();
        //当前日期
        String currDate = DateUtil.now().substring(0,10);
        while(true){
            log.info("日期{}",currDate);
            if(beginDate.equals(currDate)){
                //todo 当前日期, 查询订单表
                BizCancelOrderStatistics bizOrderStatistics = getCurrData(beginDate,0,0,0);
                bizOrderStatisticsList.add(bizOrderStatistics);
            }else{
                //非当前日期，查询统计表
                BizCancelOrderStatistics bizOrderStatistics = getHistoryData(beginDate,0,0,0);
                bizOrderStatisticsList.add(bizOrderStatistics);
            }
            beginDate = DateUtil.offset(DateUtil.parse(beginDate), DateField.DAY_OF_MONTH,1).toString().substring(0,10);
            if(beginDate.equals(endDate)){
                if(beginDate.equals(currDate)){
                    //todo 当前日期, 查询订单表
                    BizCancelOrderStatistics bizOrderStatistics = getCurrData(beginDate,0,0,0);
                    bizOrderStatisticsList.add(bizOrderStatistics);
                }else{
                    //非当前日期，查询统计表
                    BizCancelOrderStatistics bizOrderStatistics = getHistoryData(beginDate,0,0,0);
                    bizOrderStatisticsList.add(bizOrderStatistics);
                }
                break;
            }
        }
        return bizOrderStatisticsList;
    }

    @Override
    public List<BizOrderCompareStatisticsDTO> getCompareDataByDate(List<BizCancelOrderStatistics> bizCancelOrderStatisticsList, BizOrderStatisticsQuery bizOrderStatisticsQuery, String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取开始日期前一天数据
        String beginDate = bizOrderStatisticsQuery.getBeginDate();
        BizCancelOrderStatistics bizOrderStatistics = new BizCancelOrderStatistics();
        if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getBeginDate()) && bizOrderStatisticsQuery.getIsQuarter() == 0) {
            bizOrderStatistics = getHistoryData(DateUtil.offset(DateUtil.parse(beginDate), DateField.DAY_OF_MONTH, -1).toString().substring(0, 10), 0, 0, 0);
        }else{
            if(bizOrderStatisticsQuery.getIsQuarter() == 0) {
                bizOrderStatistics = getHistoryData(DateUtil.offset(DateUtil.parse(bizOrderStatisticsQuery.getBeginMonth() + "-01"), DateField.MONTH, -1).toString().substring(0, 7), 0, 0, 1);
            }else{
                int q = DateUtil.quarter(DateUtil.parse(DateUtil.now()));
                if(q == 1){
                    bizOrderStatisticsQuery.setYear(bizOrderStatisticsQuery.getYear()-1);
                    bizOrderStatisticsQuery.setQuarter(4);
                }else{
                    bizOrderStatisticsQuery.setQuarter(bizOrderStatisticsQuery.getQuarter()-1);
                }
                BizOrderStatistics orderStatistics = bizOrderStatisticsService.getHistoryData(DateUtil.now(),0,0,2,bizOrderStatisticsQuery);
                BeanUtils.copyProperties(orderStatistics,bizOrderStatistics);
            }
        }
        int length = bizCancelOrderStatisticsList.size();
        //金额
        BizOrderCompareStatisticsDTO orderMoney = getOrderStatisticsDTO("当期","bar","");
        List<String> orderMoneyList = new ArrayList<>();
        //环比(前一天)
        BizOrderCompareStatisticsDTO orderMoney1 = getOrderStatisticsDTO("环比","bar","");
        List<String> orderMoneyList1 = new ArrayList<>();
        //同比(上一年)
        BizOrderCompareStatisticsDTO orderMoney2 = getOrderStatisticsDTO("同比","bar","");
        List<String> orderMoneyList2 = new ArrayList<>();
        BizCancelOrderStatistics orderStatistics = new BizCancelOrderStatistics();
        for(int i = 0;i < length;i++){
            orderStatistics = bizCancelOrderStatisticsList.get(i);
            Method m = orderStatistics.getClass().getMethod("get" + attributeName);
            Object value = m.invoke(orderStatistics);
            orderMoneyList.add(value.toString());
            if(i == 0){
                m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
                value = m.invoke(bizOrderStatistics);
                orderMoneyList1.add(value.toString());
            }else{
                orderStatistics = bizCancelOrderStatisticsList.get(i-1);
                m = orderStatistics.getClass().getMethod("get" + attributeName);
                value = m.invoke(orderStatistics);
                orderMoneyList1.add(value.toString());
            }
            if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getBeginDate())) {
                orderStatistics = getHistoryData(DateUtil.offset(DateUtil.parse(beginDate), DateField.YEAR, -1).toString().substring(0, 10), 0, 0, 0);
            }else{
                if(bizOrderStatisticsQuery.getIsQuarter() == 1){
                    bizOrderStatisticsQuery.setYear(bizOrderStatisticsQuery.getYear()-1);
                    BizOrderStatistics orderStatistics1 = bizOrderStatisticsService.getHistoryData(DateUtil.now(),0,0,2,bizOrderStatisticsQuery);
                    BeanUtils.copyProperties(orderStatistics1,orderStatistics);
                }else {
                    orderStatistics = getHistoryData(DateUtil.offset(DateUtil.parse(bizOrderStatisticsQuery.getBeginMonth() + "-01"), DateField.YEAR, -1).toString().substring(0, 7), 0, 0, 1);
                }
            }
            m = orderStatistics.getClass().getMethod("get" + attributeName);
            value = m.invoke(orderStatistics);
            orderMoneyList2.add(value.toString());
        }
        orderMoney.setData(orderMoneyList);
        orderMoney1.setData(orderMoneyList1);
        orderMoney2.setData(orderMoneyList2);
        List<BizOrderCompareStatisticsDTO> bizOrderStatisticsDTOList = new ArrayList<>();
        bizOrderStatisticsDTOList.add(orderMoney);
        bizOrderStatisticsDTOList.add(orderMoney1);
        bizOrderStatisticsDTOList.add(orderMoney2);
        return bizOrderStatisticsDTOList;
    }

    @Override
    public List<BizCancelOrderStatistics> getListByMonth(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        String currMonth = DateUtil.now().toString().substring(0,7);
        String beginMonth = bizOrderStatisticsQuery.getBeginMonth();
        String endMonth = bizOrderStatisticsQuery.getEndMonth();
        List<BizCancelOrderStatistics> bizOrderStatisticsList = new ArrayList<>();
        while(true){
            log.info("月份数据{}",beginMonth);
            BizCancelOrderStatistics bizOrderStatistics = getHistoryData(beginMonth,0,0,1);
            bizOrderStatisticsList.add(bizOrderStatistics);
            beginMonth = DateUtil.offset(DateUtil.parse(beginMonth+"-01"), DateField.MONTH,1).toString().substring(0,7);
            if(beginMonth.equals(currMonth)){
                //查询当天数据
                BizCancelOrderStatistics currDayData = getCurrData(DateUtil.now().toString().substring(0,10),0,0,0);
                log.info("需要加上当天数据{}",beginMonth);
                bizOrderStatistics = getHistoryData(beginMonth,0,0,1);
                objAdd(bizOrderStatistics,currDayData);
                bizOrderStatisticsList.add(bizOrderStatistics);
            }
            if(beginMonth.equals(endMonth)) {
                //log.info("当前月份数据{}",beginMonth);
                if(!beginMonth.equals(currMonth)){
                    //最后结束月份不等于当前月份，查数据,不包含当月
                    bizOrderStatistics = getHistoryData(beginMonth,0,0,1);
                    bizOrderStatisticsList.add(bizOrderStatistics);
                }
                break;
            }
        }
        return bizOrderStatisticsList;
    }


    public BizOrderCompareStatisticsDTO getOrderStatisticsDTO(String name,String type,String color){
        BizOrderCompareStatisticsDTO bizOrderStatisticsDTO = new BizOrderCompareStatisticsDTO();
        bizOrderStatisticsDTO.setName(name);
        bizOrderStatisticsDTO.setType(type);
        bizOrderStatisticsDTO.setColor(color);
        return bizOrderStatisticsDTO;
    }

    /**
     * 两个类相加
     * @param obj1
     * @param obj2
     */
    public void objAdd(BizCancelOrderStatistics obj1,BizCancelOrderStatistics obj2){
        obj1.setOrderNum(obj1.getOrderUserNum() + obj2.getOrderNum());
        obj1.setOrderMoney(obj1.getOrderMoney().add(obj2.getOrderMoney()));
        obj1.setCostMoney(obj1.getCostMoney().add(obj2.getCostMoney()));
        obj1.setManNum(obj1.getManNum()+obj2.getManNum());
        obj1.setManOrderMoney(obj1.getManOrderMoney().add(obj2.getManOrderMoney()));
        obj1.setOrderUserNum(obj1.getOrderUserNum() + obj2.getOrderUserNum());
        obj1.setWomanNum(obj1.getWomanNum() + obj2.getWomanNum());
        obj1.setWomanOrderMoney(obj1.getWomanOrderMoney().add(obj2.getWomanOrderMoney()));
        obj1.setOther(obj1.getOther() + obj2.getOther());
        obj1.setOtherOrderMoney(obj1.getOtherOrderMoney().add(obj2.getOtherOrderMoney()));

    }


    /**
     * 获取历史日期数据
     * @param currDate
     * @param platformId
     * @param platformType
     * @param dateType 日期类型:0 按日，1按月，2 按照
     * @return
     */
    private BizCancelOrderStatistics getHistoryData(String currDate,Integer platformId,Integer platformType,Integer dateType){
        String key = "order:cancel:statistics:"+platformId+":"+platformType+":"+currDate;
        Object obj = redisTemplate.opsForValue().get(key);
        if(obj == null) {
            BizCancelOrderStatistics bizOrderStatistics = bizCancelOrderStatisticsMapper.getHistoryData(currDate,dateType);
            if (bizOrderStatistics == null) {
                bizOrderStatistics = new BizCancelOrderStatistics();
                bizOrderStatistics.setPlatformId(0);
            }
            getDetail(bizOrderStatistics, currDate);
            //数据写入redis
            String jsonString = JSONObject.toJSONString(bizOrderStatistics);
            Integer num = RandomUtil.randomInt(3600, 7200);
            redisTemplate.opsForValue().set(key, jsonString, num, TimeUnit.SECONDS);
            return bizOrderStatistics;
        }else{
            BizCancelOrderStatistics bizOrderStatistics = JSONObject.parseObject(obj.toString(),BizCancelOrderStatistics.class);
            return bizOrderStatistics;
        }
    }

    /**
     * 获取当前日期数据
     * @param currDate
     * @param platformId
     * @param platformType
     * @return
     */
    private BizCancelOrderStatistics getCurrData(String currDate,Integer platformId,Integer platformType,Integer dateType){
        String key = "order:cancel:statistics:"+platformId+":"+platformType+":"+currDate;
        Object obj = redisTemplate.opsForValue().get(key);
        if(obj == null) {
            BizCancelOrderStatistics bizOrderStatistics = bizCancelOrderStatisticsMapper.statisticsOrderByData(currDate,dateType);
            if (bizOrderStatistics.getPlatformId() == null) {
                bizOrderStatistics = new BizCancelOrderStatistics();
            }
            bizOrderStatistics.setPlatformId(0);
            getDetail(bizOrderStatistics, currDate);
            String jsonString = JSONObject.toJSONString(bizOrderStatistics);
            //缓存300秒
            redisTemplate.opsForValue().set(key, jsonString, 300, TimeUnit.SECONDS);
            return bizOrderStatistics;
        }else{
            BizCancelOrderStatistics bizOrderStatistics = JSONObject.parseObject(obj.toString(),BizCancelOrderStatistics.class);
            return bizOrderStatistics;
        }
    }

    private void getDetail(BizCancelOrderStatistics bizOrderStatistics, String date){
        bizOrderStatistics.setCurrYear(date.substring(0,4));
        bizOrderStatistics.setCurrMonth(date.substring(0,7));
        try {
            bizOrderStatistics.setYearDay(date.substring(0, 10));
        }catch (Exception e){
            bizOrderStatistics.setYearDay("");
        }
        bizOrderStatistics.setYearQ(1);
        //bizOrderStatistics.setYearQ(DateUtil.quarter(DateUtil.parse(date)));
    }
}
